package com.tsfot.spider.network;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpSender {

	private final static Logger logger = LoggerFactory.getLogger(HttpSender.class);

	private final static int RETRY_TIME = 3;

	private static HttpSender instance;
	
	private RequestConfig requestConfig = RequestConfig.custom()  
            .setSocketTimeout(15000)  
            .setConnectTimeout(15000)  
            .setConnectionRequestTimeout(15000)  
            .build();

	private HttpSender() {
	}

	public static HttpSender getInstance() {
		if (instance == null) {
			instance = new HttpSender();
		}
		return instance;
	}

	private HttpGet getHttpGet(String url) {
		HttpGet httpGet = new HttpGet(url);
		setHeader(httpGet);
		return httpGet;
	}
	
	private HttpPost getHttpPost(String url) {
		HttpPost httpPost = new HttpPost(url);
		setHeader(httpPost);
		return httpPost;
	}
	
	public InputStream downloadImage(String url){
		HttpGet httpGet = null;
		String responseBody = "";
		CloseableHttpResponse response = null;
		CloseableHttpClient httpclient = HttpClients.createDefault();
		httpGet = getHttpGet(url);
		httpGet.setConfig(requestConfig);
		try {
			response = httpclient.execute(httpGet);
			// 返回结果
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != HttpStatus.SC_OK) {
				logger.info("下载图片【{}】出错！远程服务返回{}",url,statusCode);
				return null;
			}else{
				HttpEntity entity = response.getEntity();
				return entity.getContent();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	

	public String sendHttpGet(String url) {
		HttpGet httpGet = null;
		String responseBody = "";
		CloseableHttpResponse response = null;
		int time = 0;
		do {
			try {
				CloseableHttpClient httpclient = HttpClients.createDefault();
				httpGet = getHttpGet(url);
				httpGet.setConfig(requestConfig);
				response = httpclient.execute(httpGet);
				// 返回结果
				int statusCode = response.getStatusLine().getStatusCode();
				if (statusCode != HttpStatus.SC_OK) {
						
				}
				responseBody = EntityUtils.toString(response.getEntity());
				
				break;
			} catch (ClientProtocolException e) {
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				// 发生致命的异常，可能是协议不对或者返回的内容有问题
				e.printStackTrace();
				logger.error("请求URL:{}时出现网络协议错误！",url);
			} catch (IOException e) {
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				// 发生网络异常
				e.printStackTrace();
				logger.error("请求URL:{}时出现网络错误！",url);
			} finally {
				// 释放连接
				try {
					httpGet.releaseConnection();
					if (response != null){
						response.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
					logger.error("关闭连接URL:{}时出现错误！",url);
				}
			}
		} while (time < RETRY_TIME);
		
		return responseBody;
	}

	
	public String sendHttpPost(String httpUrl, Map<String, String> params,List<File> fileLists) {
		
		CloseableHttpClient httpClient = null;  
        CloseableHttpResponse httpResponse = null;  
        String responseBody = "";
		int time = 0;
		
		HttpPost httpPost = getHttpPost(httpUrl);
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();  
		builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        for (String key : params.keySet()) {  
        	builder.addTextBody(key, params.get(key), ContentType.TEXT_PLAIN);
        }  
        for(File file : fileLists) {  
            FileBody fileBody = new FileBody(file);  
            builder.addPart("files", fileBody);  
        }  
        HttpEntity reqEntity = builder.build();  
        httpPost.setEntity(reqEntity);
        
		do {
			try {
				httpClient = HttpClients.createDefault();
				httpPost.setEntity(reqEntity);
				httpResponse = httpClient.execute(httpPost);
				int statusCode = httpResponse.getStatusLine().getStatusCode();
				if (statusCode != HttpStatus.SC_OK) {
					 
				}
				responseBody = EntityUtils.toString(httpResponse.getEntity());
				break;
			} catch (ClientProtocolException e) {
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				// 发生致命的异常，可能是协议不对或者返回的内容有问题
				e.printStackTrace();
				logger.error("请求URL:{}时出现网络协议错误！",httpUrl);
			} catch (IOException e) {
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				// 发生网络异常
				e.printStackTrace();
				logger.error("请求URL:{}时出现网络错误！",httpUrl);
			} finally {
				// 释放连接
				try {
					httpPost.releaseConnection();
					if (httpResponse != null)httpResponse.close();
					if (httpClient != null)httpClient = null;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} while (time < RETRY_TIME);

		return responseBody;
	}

	private void setHeader(HttpGet httpGet) {
		httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36");
	}
	
	private void setHeader(HttpPost httpPost) {
		httpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36");
	}
	

}